#include "../base/random.h"
#include "../base/logger.h"
#include "vec2.h"
#include "vec3.h"
#include "vec4.h"
#include "box2.h"
#include "box3.h"
#include "mat4.h"


USE_JLIB_NS

static Random r;

f32 rscalar () {
  return r.uniformf(-1.0F, 1.0F);
}
Vec2 rvec2 () {
  f32 x = r.uniformf(-1.0F, 1.0F);
  f32 y = r.uniformf(-1.0F, 1.0F);
  return {x, y};
}
Vec3 rvec3 () {
  f32 x = r.uniformf(-1.0F, 1.0F);
  f32 y = r.uniformf(-1.0F, 1.0F);
  f32 z = r.uniformf(-1.0F, 1.0F);
  return {x, y, z};
}
f32v4 rvec4 () {
  f32 x = r.uniformf(-1.0F, 1.0F);
  f32 y = r.uniformf(-1.0F, 1.0F);
  f32 z = r.uniformf(-1.0F, 1.0F);
  f32 w = r.uniformf(-1.0F, 1.0F);
  return f32v4{x, y, z, w};
}
Box2 rbox2 () {
  f32 x = r.uniformf<f32>(-1.0F, 0.0F);
  f32 y = r.uniformf<f32>(-1.0F, 0.0F);
  f32 X = r.uniformf<f32>( 0.0F, 1.0F);
  f32 Y = r.uniformf<f32>( 0.0F, 1.0F);
  return {x, y, X, Y};
}
Box3 rbox3 () {
  f32 x = r.uniformf<f32>(-1.0F, 0.0F);
  f32 y = r.uniformf<f32>(-1.0F, 0.0F);
  f32 z = r.uniformf<f32>(-1.0F, 0.0F);
  f32 X = r.uniformf<f32>( 0.0F, 1.0F);
  f32 Y = r.uniformf<f32>( 0.0F, 1.0F);
  f32 Z = r.uniformf<f32>( 0.0F, 1.0F);
  return {x, y, z, X, Y, Z};
}
Mat4 rmat4 () {
  f32 s00 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s01 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s02 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s03 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s10 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s11 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s12 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s13 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s20 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s21 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s22 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s23 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s30 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s31 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s32 = r.uniformf<f32>(-1.0F, 1.0F);
  f32 s33 = r.uniformf<f32>(-1.0F, 1.0F);
  return {
    s00, s10, s20, s30,
    s01, s11, s21, s31,
    s02, s12, s22, s32,
    s03, s13, s23, s33,
  };
}


void pboolean (const char* i, bool v) {
  log_i("%s: %s", i, v ? "True" : "False");
}
void pscalar (const char* i, f32 v) {
  log_i("%s: %f", i, v);
}
void pvec2 (const char* i, Vec2 v) {
  log_i("%s: { %f, %f }", i, v.x(), v.y());
}
void pvec3 (const char* i, Vec3 v) {
  log_i("%s: { %f, %f, %f }", i, v.x(), v.y(), v.z());
}
void pvec4 (const char* i, Vec4 v) {
  log_i("%s: { %f, %f, %f, %f }", i, v.x(), v.y(), v.z(), v.w());
}
void pbox2 (const char* i, Box2 v) {
  log_i("%s: { %f, %f }, { %f, %f }", i, v.x(), v.y(), v.X(), v.Y());
}
void pbox3 (const char* i, const Box3& v) {
  log_i("%s: { %f, %f, %f }, { %f, %f, %f }", i, v.x(), v.y(), v.z(), v.X(), v.Y(), v.Z());
}
void pmat4 (const char* i, const Mat4& m) {
  log_i("%s: {\n\t%f, %f, %f, %f\n\t%f, %f, %f, %f\n\t%f, %f, %f, %f\n\t%f, %f, %f, %f\n}", i
    , m.c<0>(), m.c<4>(), m.c<8>(), m.c<12>()
    , m.c<1>(), m.c<5>(), m.c<9>(), m.c<13>()
    , m.c<2>(), m.c<6>(), m.c<10>(), m.c<14>()
    , m.c<3>(), m.c<7>(), m.c<11>(), m.c<15>());
}
